/* ****************************************************************************
 *
 * Copyright (c) Microsoft Corporation. 
 *
 * This source code is subject to terms and conditions of the Microsoft Public License. A 
 * copy of the license can be found in the License.html file at the root of this distribution. If 
 * you cannot locate the  Microsoft Public License, please send an email to 
 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
 * by the terms of the Microsoft Public License.
 *
 * You must not remove this notice, or any other, from this software.
 *
 * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
 * PARTICULAR PURPOSE.
 * ***************************************************************************/



#ifndef PGLCOREDLL_H
	#define PGLCOREDLL_H

#include <afxcmn.h>
#include <afxdisp.h> 
#include <afxtempl.h>
#include <afxdlgs.h>
#include <afxwin.h>
#include <oleauto.h>
#include <time.h>
#include <sys/types.h>
#include <sys/timeb.h>

#include <boost/smart_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <pgl/core/static_ptr.hpp>

//#define _PGL_SHAREWARE
#define _MFC_7_MSCP1_2844

#include <pgl/algotools/AlgoTools.h>
#include <pgl/igfx/STLIGfx.h>
#include <pgl/igfx/GfxInterface.h>
#include <pgl/igfx/GDIpInterface.h>
#include <pgl/igfx/GDIpHelper.h>

////////////////////////////////////////////////////////////////////////////////////////////////
// Including libraries
/*
#ifndef _PGLCORE_DLL
#ifndef _PGLCORE_DLL_LOADED
#define _PGLCORE_DLL_LOADED

		#if _MSC_VER >= 1300
			#ifdef _DEBUG
				#ifdef _UNICODE
					#pragma message("     _Adding library: PGLCore8ud.lib: MFC8.0,dll, Debug, UNICODE" ) 
					#pragma comment(lib, "PGLCore8ud.lib")
				#else
					#pragma message("     _Adding library: PGLCore8d.lib: MFC8.0,dll, Debug, MBCS" ) 
					#pragma comment(lib, "PGLCore8d.lib")
				#endif
			#else
				#ifdef _UNICODE
					#pragma message("     _Adding library: PGLCore8u.lib: MFC8.0,dll, Release, UNICODE" ) 
					#pragma comment(lib, "PGLCore8u.lib")
				#else
					#pragma message("     _Adding library: PGLCore8.lib: MFC8.0, dll,Release, MBCS" ) 
					#pragma comment(lib, "PGLCore8.lib")
				#endif
			#endif
		#else
			#ifdef _DEBUG
				#ifdef _UNICODE
					#pragma message("     _Adding library: PGLCoreud.lib: MFC4.2,dll, Debug, UNICODE" ) 
					#pragma comment(lib, "PGLCoreud.lib")
				#else
					#pragma message("     _Adding library: PGLCored.lib: MFC4.2, dll,Debug, MBCS" ) 
					#pragma comment(lib, "PGLCored.lib")
				#endif
			#else
				#ifdef _UNICODE
					#pragma message("     _Adding library: PGLCoreu.lib: MFC4.2,dll, Release, UNICODE" ) 
					#pragma comment(lib, "PGLCoreu.lib")
				#else
					#pragma message("     _Adding library: PGLCore.lib: MFC4.2,dll, Release, MBCS" ) 
					#pragma comment(lib, "PGLCore.lib")
				#endif
			#endif
		#endif

#endif
#endif
		*/

///////////////////////////////////////////////////////////////////////////////////////
// min max handling
// del [5/8/2009 JYB]
// #ifdef max
// 	#undef max
// #endif
// #ifdef min
// 	#undef min
// #endif
// 
// namespace pgl 
// { 
//   template <typename T> 
//   inline const T& min(const T& a, const T& b) 
//   { return b < a ? b : a; } 
// 
//   template <typename T> 
//   inline const T& max(const T& a, const T& b) 
//   { return  a < b ? b : a; } 
// } 



#pragma warning(disable: 4800)
#pragma warning(disable: 4786)  // identifier was truncated to 'number' characters in the debug information

#undef PGLCORE_EXT_CLASS
#ifdef _DLL
	#ifndef PGLCORE_EXT_CLASS
		#ifdef _PGLCORE_DLL
			#define PGLCORE_EXT_CLASS _declspec(dllexport)
		#else
			#define PGLCORE_EXT_CLASS _declspec(dllimport)
		#endif
	#endif
#else
	#define PGLCORE_EXT_CLASS
#endif

#include "Logger.h"

#ifndef PGL_TRACE
	#ifdef _DEBUG
			#define PGL_TRACE(sz)			{	TRACE(sz); pgl::CLoggerSingleton::Log(__FILE__,__LINE__, sz);};
			#define PGL_TRACE0(sz)			{	TRACE(sz); pgl::CLoggerSingleton::Log(__FILE__,__LINE__, sz);};
			#define PGL_TRACE1(sz,a)		{	TRACE(sz,a); pgl::CLoggerSingleton::Log(__FILE__,__LINE__, sz,a);};
			#define PGL_TRACE2(sz,a,b)		{	TRACE(sz,a,b); pgl::CLoggerSingleton::Log(__FILE__,__LINE__, sz,a,b);};
			#define PGL_TRACE3(sz,a,b,c)	{	TRACE(sz,a,b,c); pgl::CLoggerSingleton::Log(__FILE__,__LINE__, sz,a,b,c);};
	#else 
			#define PGL_TRACE(sz)			{ pgl::CLoggerSingleton::Log(__FILE__,__LINE__, sz);};
			#define PGL_TRACE0(sz)			{ pgl::CLoggerSingleton::Log(__FILE__,__LINE__, sz);};
			#define PGL_TRACE1(sz, a)		{ pgl::CLoggerSingleton::Log(__FILE__,__LINE__, sz,a);};
			#define PGL_TRACE2(sz, a, b)	{ pgl::CLoggerSingleton::Log(__FILE__,__LINE__, sz,a,b);};
			#define PGL_TRACE3(sz, a, b, c) { pgl::CLoggerSingleton::Log(__FILE__,__LINE__, sz,a,b,c);};
	#endif
#endif

///////////////////////////////////////////////////////////////////////////////////////
// Smart pointer
#ifndef PGL_DECLARE_SMARTPTR
#define PGL_DECLARE_SMARTPTR( className ) \
	typedef boost::shared_ptr< className > className ##Ptr;\
	typedef boost::weak_ptr< className > className ##WkPtr; \
	typedef boost::static_ptr< className > className ##StPtr;
#endif

///////////////////////////////////////////////////////////////////////////////////////
// Dyncreate
#ifndef PGL_DECLARE_DYNCREATE
	#define PGL_DECLARE_DYNCREATE(CChild) \
	DECLARE_DYNCREATE(CChild);\
public:\
	virtual CPGLNodePtr MakeCopy() const \
	{	return boost::shared_polymorphic_cast<CPGLNode,CChild>( boost::shared_ptr<CChild>( new CChild(*this) ) ); };\
	static CPGLNodePtr GetEmpty ## CChild ();
#endif

//! Implement of dynamic creation macro
#ifndef PGL_IMPLEMENT_DYNCREATE
		#define PGL_IMPLEMENT_DYNCREATE(CChild,CParent) \
		IMPLEMENT_DYNCREATE(CChild,CParent); \
		CPGLNodePtr CChild::GetEmpty ## CChild ()\
		{\
		return boost::shared_polymorphic_cast<CPGLNode,CChild>( boost::shared_ptr<CChild>(new CChild));\
		};\
namespace pgl { namespace priv { static CNodeRegisterer chartingObject##CChild( _T( #CChild ), CChild::GetEmpty ## CChild );};}; 
#endif

///////////////////////////////////////////////////////////////////////////////////////
// scripting declaration macro
#ifndef PGL_DECLARE_SCRIPTING
#define PGL_DECLARE_SCRIPTING( className )\
public:\
	static E##className ##Prop StringTo ##className ##Prop ( LPCTSTR szProp);\
	virtual bool SetProperty( LPCTSTR szProp, LPCTSTR szValue);\
	virtual bool Get( LPCTSTR szProp, CString& str);\
	virtual void Help( CString& str) const;\
protected:\
	virtual void PreparePropertyMap();\
public:
#endif

//! Getting help of scripting
#define PGL_GET_HELP( className, str ) \
{ PropertyMap::const_iterator it; \
str+="PGL" #className " :\r\n-----------------\r\n";\
for (it= m_mProps.begin();it!= m_mProps.end(); ++it)\
{\
	str+=it->first;\
	str+=_T("\t");\
	str+=it->second.second;\
	str+=_T("\r\n");\
}\
};

//! Implement scripting
#ifndef PGL_IMPLEMENT_SCRIPTING
#define PGL_IMPLEMENT_SCRIPTING( className )\
void CPGL ##className::Help(CString& str) const \
{\
	str.Empty(); PGL_GET_HELP( className, str );\
};\
CPGL ##className::E##className ##Prop CPGL ##className::StringTo ##className ##Prop ( LPCTSTR szProp)\
{	\
	static const CString sClassName(#className ".");\
	return (E##className ##Prop)m_mProps[sClassName+szProp].first;\
};
#endif

#ifndef PGL_ASSERT_VALID
	#define PGL_ASSERT_VALID( ptr )	 ASSERT_VALID( ptr.get() );
#endif

#include <pgl/core/PGLCoreGlobal.h>
#include <pgl/core/PGLDef.h>
#include <pgl/core/PGLResource.h>
#include <pgl/core/PGLObjectRegistry.h>
#include <pgl/core/PGLUtility.h>
#ifndef _PGLCORE_DLL
	#include <pgl/core/PGLInclude.h>
#endif

#endif
